<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
	Function.prototype.method= function(name,func){
		this.prototype[name] = func;
		return this;
	}
	
	Object.method("superior",function(name){     //super를 호출할수 있게 해준다 하단 coolCat 예제 참조
		var that = this, method = that[name];
		return function(){
			return method.apply(that,arguments);
		};
	});
	
	var mammal = function(spec){
		var that = {};
		that.get_name = function(){
			return spec.name;
		};
		that.says = function(){
			return spec.saying ||"";
		};
		
		return that;
	}
	
	var cat = function(spec){
		spec.saying = spec.saying || "meow";
		var that = mammal(spec);
		
		that.perr = function(n){
			var i,s ="";
			for(i=0;i<n;i++){
				if(s){
					s+="-";
				}
				s+="r";
			}
			return s;
		};
		that.get_name = function(){
			return that.says()+" "+spec.name+" "+that.says();
		};
		return that;
	}
	
	var coolCat = function(spec){
		var that = cat(spec);
		var super_get_name = that.superior("get_name");    //super의 get_name호출
		that.get_name = function(n){
			return 'like ' + super_get_name()+ ' body';
		};
		return that;
	}
	
	
	
	//new 연산자를 사용해서 생성자를 호출하는 경우와 생성자를 그냥 호출하는 경우의 차이는 생성자에서 객체를 반환하느냐 아니냐(객체를 정의만 하느냐)의 차이 본 예제는 객체반환한다. 
	var myMammal = mammal({name:"Herb",saying:"none"});  
	//pt(myMammal.says()+myMammal.get_name());
	
	var myCat = cat({name:"husky"});
	var cCat = coolCat({name:"cuty"});
	
	
	
	pt(myMammal.says()+" --- "+myMammal.get_name());
	pt(myCat.says()+" --- "+myCat.get_name());
	pt(cCat.says()+" --- "+cCat.get_name());
	
	function pt(str){
		document.write("<br>"+str);
	}
</script>
</head>
<body>

</body>
</html>